package com.yupi.yoj.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yupi.yoj.common.ErrorCode;
import com.yupi.yoj.exception.ThrowUtils;
import com.yupi.yoj.mapper.ContestUserMapper;
import com.yupi.yoj.model.dto.contestuser.ContestUserJoinRequest;
import com.yupi.yoj.model.entity.Contest;
import com.yupi.yoj.model.entity.ContestUser;
import com.yupi.yoj.model.entity.QuestionSubmit;
import com.yupi.yoj.model.vo.ContestUserVO;
import com.yupi.yoj.model.vo.ContestVO;
import com.yupi.yoj.model.vo.QuestionSubmitVO;
import com.yupi.yoj.service.ContestService;
import com.yupi.yoj.service.ContestUserService;
import com.yupi.yoj.service.QuestionService;
import com.yupi.yoj.service.QuestionSubmitService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author 46411
 * @description 针对表【contest_user(竞赛参加用户关联表)】的数据库操作Service实现
 * @createDate 2024-10-05 01:13:37
 */
@Service
public class ContestUserServiceImpl extends ServiceImpl<ContestUserMapper, ContestUser>
        implements ContestUserService {

    @Autowired
    QuestionService questionService ;

    @Autowired
    QuestionSubmitService questionSubmitService;

    @Autowired
    ContestService contestService;

    @Override
    public void validContestUser(ContestUser contestUser) {
        Long contestid = contestUser.getContestid();
        Long userid = contestUser.getUserid();
        String subids = contestUser.getSubids();

        ThrowUtils.throwIf(contestid <= 0 || userid <= 0 || subids != null, ErrorCode.PARAMS_ERROR, "参数错误");

    }

    @Override
    public ContestUserVO getContestUserVO(ContestUser contestUser) {
        ContestUserVO contestUserVO = new ContestUserVO();
        BeanUtils.copyProperties(contestUser, contestUserVO);
        String subids = contestUser.getSubids();
        ThrowUtils.throwIf(StringUtils.isAnyBlank(subids), ErrorCode.PARAMS_ERROR, "参数错误");
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            Long[] proSubids = objectMapper.readValue(subids, Long[].class);
            if (proSubids != null) contestUserVO.setSubids(Arrays.asList(proSubids));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return contestUserVO;
    }

    @Override
    public List<ContestUserVO> getContestUserVO(List<ContestUser> contestUser) {
        LinkedList<ContestUserVO> contestUsers = new LinkedList<>();
        for (int i = 0; i < contestUser.size(); i++) {
            ContestUserVO contestUserVO = getContestUserVO(contestUser.get(i));
            contestUsers.add(contestUserVO);
        }
        return contestUsers;
    }

    @Override
    public void updateSubids(Long subid, Long contestid, Long userid) {
        QueryWrapper<ContestUser> contestUserQueryWrapper = new QueryWrapper<ContestUser>().eq("contestId", contestid).eq("userId", userid);
        // 查询用户竞赛
        ContestUser contestUser = this.getOne(
                contestUserQueryWrapper
        );
        ThrowUtils.throwIf(contestUser == null, ErrorCode.NOT_FOUND_ERROR, "用户竞赛未参加竞赛");
        String subids = contestUser.getSubids();
        String subidsArrjsonStr = null;
        if (StringUtils.isNotBlank(subids)) {
            Long[] subidsArr = JSONUtil.parseArray(subids).toArray(new Long[0]);
            List<Long> subidsList = Arrays.asList(subidsArr);
            subidsList.add(subid);
            subidsArr = subidsList.toArray(new Long[0]);
            subidsArrjsonStr = JSONUtil.toJsonStr(subidsArr);
        }else {
            List<Long> subidsList = new LinkedList<>();
            subidsList.add(subid);
            Long[] subidsArr = subidsList.toArray(new Long[0]);
            subidsArrjsonStr = JSONUtil.toJsonStr(subidsArr);
        }
        contestUser.setSubids(subidsArrjsonStr);
        UpdateWrapper<ContestUser> contestUserUpdateWrapper = new UpdateWrapper<>();
        contestUserUpdateWrapper.set("subids", subidsArrjsonStr).eq("contestId", contestid).eq("userId", userid);
        this.update(contestUserUpdateWrapper);
    }

    @Override
    public void isJoin(Long contestid, Long userid) {
        QueryWrapper<ContestUser> contestUserQueryWrapper = new QueryWrapper<ContestUser>().eq("contestId", contestid).eq("userId", userid);
        // 查询用户竞赛
        ContestUser contestUser = this.getOne(
                contestUserQueryWrapper
        );
        ThrowUtils.throwIf (contestUser == null, ErrorCode.NOT_FOUND_ERROR, "用户竞赛未参加竞赛");
    }

    @Override
    public Long join(ContestUserJoinRequest contestUserJoinRequest) {
        ThrowUtils.throwIf (contestUserJoinRequest == null, ErrorCode.PARAMS_ERROR, "参数为空");
        ContestUser contestUser = new ContestUser();
        BeanUtils.copyProperties(contestUserJoinRequest, contestUser);
        ThrowUtils.throwIf(!this.save(contestUser), ErrorCode.SYSTEM_ERROR, "添加失败");
        Long id = contestUser.getId();
        ContestUser contestUserbyId = this.getById(id);
        ThrowUtils.throwIf(contestUserbyId == null, ErrorCode.NOT_FOUND_ERROR, "添加失败");
        return id;
    }

    /**
     * 获取还没计算结果的竞赛记录
     * @return
     */
    @Override
    public List<ContestUser> getUnEndContest() {
        QueryWrapper<ContestUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.isNull("resulte");
        return this.list(queryWrapper);
    }

    @Override
    public void calculateContestScore(ContestUser contestUser) {
        Long contestid = contestUser.getContestid();
        String subids = contestUser.getSubids();
        Long[] subidsArr = null;
        if (StringUtils.isNotBlank(subids)) {
            subidsArr = JSONUtil.parseArray(subids).toArray(new Long[0]);
        }
        Contest contestbyId = contestService.getById(contestid);


        ThrowUtils.throwIf(contestbyId==null, ErrorCode.NOT_FOUND_ERROR, "竞赛不存在");
        String tscores = contestbyId.getTscores();
        ThrowUtils.throwIf(StringUtils.isBlank(tscores), ErrorCode.PARAMS_ERROR, "竞赛未指定分数");
        Integer[] scoreArr = JSONUtil.parseArray(tscores).toArray(new Integer[0]);

        String tids = contestbyId.getTids();
        ThrowUtils.throwIf(StringUtils.isBlank(tids), ErrorCode.PARAMS_ERROR, "竞赛未指定分数");
        Long[] tidsArr = JSONUtil.parseArray(tids).toArray(new Long[0]);
        ThrowUtils.throwIf(tidsArr.length != scoreArr.length, ErrorCode.SYSTEM_ERROR, "分数定义和题目定义数量不一致");
        // 分数映射
        Map<Long, Integer> scoreMap = new HashMap<>();
        for (int i = 0; i < tidsArr.length; i++) {
            scoreMap.put(tidsArr[i], scoreArr[i]);
        }
        // 每题得分map
        Map<Long, Integer> getScoreMap = new HashMap<>();
        // 查询提交列表
        List<QuestionSubmit> submits = questionSubmitService.getQuestionSubmitByIds(subidsArr);
        for (QuestionSubmit submit : submits) {
            Integer status = submit.getStatus();
            Long questionid = submit.getQuestionid();
            Integer hadGEtScore = scoreMap.get(questionid);
            // 成功
            if (status == 2) {
                getScoreMap.put(questionid, hadGEtScore);
            }
        }
        // 计算分数
        String idScoreMap = JSONUtil.toJsonStr(getScoreMap);
        contestUser.setResulte(idScoreMap);
    }
}
